package com.gooluke;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author gooluke
 * description
 * datetime 2025-04-07 21:51
 */
public class MyThreadPool {

    private int coreSize;
    private int maxSize;
    private int timeout;
    private TimeUnit timeUnit;
    private BlockingQueue<Runnable> blockingQueue;
    private MyRejectHandler rejectHandler;

    public MyThreadPool(int coreSize, int maxSize, int timeout, TimeUnit timeUnit, BlockingQueue<Runnable> blockingQueue, MyRejectHandler rejectHandler) {
        this.coreSize = coreSize;
        this.maxSize = maxSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.blockingQueue = blockingQueue;
        this.rejectHandler = rejectHandler;
    }

    List<Thread> coreThreads = new ArrayList<>();
    List<Thread> supportThreads = new ArrayList<>();

    public void execute(Runnable runnable) {
        if (coreThreads.size() < coreSize) {
            Thread thread = new CoreThread();
            coreThreads.add(thread);
            System.out.println("创建了核心线程");
            thread.start();
        }
        boolean offer = blockingQueue.offer(runnable);
        if (offer) {
            return;
        }
        if (coreThreads.size() + supportThreads.size() < maxSize) {
            Thread thread = new SupportThread();
            supportThreads.add(thread);
            System.out.println("创建了支持线程");
            thread.start();
        }
        if (!blockingQueue.offer(runnable)) {
            rejectHandler.reject(runnable, this);
        }
    }

    private class CoreThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    Runnable runnable = blockingQueue.take();
                    runnable.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        }
    }

    private class SupportThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    Runnable runnable = blockingQueue.poll(timeout, timeUnit);
                    if (runnable == null) {
                        break;
                    }
                    runnable.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public BlockingQueue<Runnable> getBlockingQueue() {
        return blockingQueue;
    }

}
